﻿using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WMS.Model;
using WMS.Repository.IRepository;
using WMS.Service.IService;

namespace WMS.Service
{
    public class MenuService : BaseServices<MenuModel>, IMenuService
    {
        private readonly IMenuRepository _menuRepository;
        private readonly IUserRoleRepository _userRoleRepository;
        private readonly IRoleMenuRepository _roleMenuRepository;

        public MenuService(IBaseRepository<MenuModel> repository,
            ILogger<BaseServices<MenuModel>> logger,
            IMenuRepository menuRepository,
            IUserRoleRepository userRoleRepository,
            IRoleMenuRepository roleMenuRepository) : base(repository, logger)
        {
            _menuRepository = menuRepository;
            _userRoleRepository = userRoleRepository;
            _roleMenuRepository = roleMenuRepository;
        }

        /// <summary>
        /// 获取菜单树列表
        /// </summary>
        public async Task<List<DynamicRouteDto>> GetMenuListAsync(bool? isEnabled = null, bool? isVisible = null)
        {
            try
            {
                var allMenus = await _menuRepository.GetAllMenusAsync();

                var query = allMenus.Where(m => m.MenuType == 1 || m.MenuType == 2)
                                   .OrderBy(m => m.SortIndex)
                                   .AsQueryable();

                if (isVisible.HasValue)
                {
                    query = query.Where(m => m.IsVisible == isVisible.Value);
                }

                if (isEnabled.HasValue)
                {
                    query = query.Where(m => m.IsEnabled == isEnabled.Value);
                }

                var routeMenus = query.ToList();
                return BuildRouteTree(routeMenus);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取菜单列表失败");
                throw;
            }
        }

        /// <summary>
        /// 动态路由
        /// </summary>
        public async Task<List<DynamicRouteDto>> GetDynamicRouterAsync(long userId)
        {
            try
            {
                List<UserRoleModel> userRoles = await _userRoleRepository.GetUserRoles(userId);
                List<long> userRoleIds = userRoles.Select(m => m.RoleId).ToList();
                List<RoleMenuModel> roleMenus = await _roleMenuRepository.GetListByRoleIdsAsync(userRoleIds);
                List<long> menuIds = roleMenus.Select(rm => rm.MenuId).Distinct().ToList();
                var query = await _menuRepository.GetDynamicRouterListAsync(menu => menuIds.Contains(menu.Id));
                return BuildRouteTree(query);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"获取动态路由失败 - 用户ID: {userId}");
                throw;
            }
        }

        /// <summary>
        /// 构建路由树
        /// </summary>
        public List<DynamicRouteDto> BuildRouteTree(List<MenuModel> menus)
        {
            var rootMenus = menus.Where(m => m.ParentMenuId == null)
                               .OrderBy(m => m.SortIndex)
                               .ToList();

            var routeTree = new List<DynamicRouteDto>();

            foreach (var menu in rootMenus)
            {
                var route = ConvertToRoute(menu);
                BuildRouteChildren(route, menus);
                routeTree.Add(route);
            }

            return routeTree;
        }

        /// <summary>
        /// 递归构建子路由
        /// </summary>
        public void BuildRouteChildren(DynamicRouteDto parentRoute, List<MenuModel> allMenus)
        {
            var children = allMenus.Where(m => m.ParentMenuId == parentRoute.Id)
                                  .OrderBy(m => m.SortIndex)
                                  .ToList();

            foreach (var child in children)
            {
                var childRoute = ConvertToRoute(child);
                parentRoute.Children.Add(childRoute);
                BuildRouteChildren(childRoute, allMenus);
            }
        }

        /// <summary>
        /// 将菜单转换为路由对象
        /// </summary>
        public DynamicRouteDto ConvertToRoute(MenuModel menu)
        {
            return new DynamicRouteDto
            {
                Id = (long)menu.Id,
                Path = menu.MenuPath,
                Code = menu.MenuCode,
                Component = menu.ComponentName,
                ParentMenuId = menu.ParentMenuId,
                Meta = new RouteMetaDto
                {
                    Title = menu.MenuName,
                    Icon = menu.MenuIcon,
                    IsVisible = menu.IsVisible,
                    IsEnabled = menu.IsEnabled,
                    MenuType = menu.MenuType,
                    SortIndex = menu.SortIndex,
                    Description = menu.Description,
                },
                Children = new List<DynamicRouteDto>()
            };
        }

        /// <summary>
        /// 获取一级菜单
        /// </summary>
        public async Task<(bool Success, string Message, object Data)> GetOneMenuList()
        {
            try
            {
                List<MenuModel> menuModel = await _menuRepository.GetOneMenuList();
                if (menuModel == null || !menuModel.Any())
                {
                    return (false, "查询失败", null);
                }
                var data = menuModel.Where(m => m.IsVisible == true && m.IsEnabled == true).Select(u => new { u.MenuName, u.Id }).ToList();
                return (true, "查询成功", data);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取一级菜单失败");
                throw;
            }
        }

        /// <summary>
        /// 添加目录/菜单
        /// </summary>
        public async Task<(bool Success, string Message)> AddMenuAsync(MenuModelDto menuModel)
        {
            try
            {
                var model = new MenuModel
                {
                    ParentMenuId = menuModel.ParentMenuId == 0 ? null : menuModel.ParentMenuId,
                    MenuCode = menuModel.MenuCode.Trim(),
                    MenuName = menuModel.MenuName.Trim(),
                    MenuPath = menuModel.MenuPath?.Trim(),
                    MenuIcon = menuModel.MenuIcon?.Trim(),
                    MenuType = menuModel.MenuType,
                    SortIndex = menuModel.SortIndex,
                    ComponentName = menuModel.ComponentName?.Trim(),
                    FullPath = menuModel.MenuPath?.Trim(),
                    Description = menuModel.Description?.Trim(),
                    IsEnabled = menuModel.IsEnabled,
                    IsVisible = menuModel.IsVisible,
                    MenuLevel = CalculateMenuLevel(menuModel.ParentMenuId, menuModel.MenuType),
                };

                return await _repository.AddAsync(model) ? (true, "添加成功！") : (false, "添加失败！");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"添加菜单失败 - 菜单名称: {menuModel?.MenuName}");
                return (false, "系统错误，添加失败");
            }
        }

        /// <summary>
        /// 计算菜单层级
        /// </summary>
        private int CalculateMenuLevel(long? parentMenuId, byte menuType)
        {
            if (parentMenuId == null)
                return 0;

            return menuType == 1 ? 0 : 1;
        }

        /// <summary>
        /// 修改菜单
        /// </summary>
        public async Task<(bool Success, string Message)> UpdateMenuAsync(MenuModelDto menuModel)
        {
            try
            {
                var model = new MenuModel
                {
                    Id = menuModel.Id,
                    ParentMenuId = menuModel.ParentMenuId,
                    MenuCode = menuModel.MenuCode.Trim(),
                    MenuName = menuModel.MenuName.Trim(),
                    MenuPath = menuModel.MenuPath?.Trim(),
                    MenuIcon = menuModel.MenuIcon?.Trim(),
                    MenuType = menuModel.MenuType,
                    SortIndex = menuModel.SortIndex,
                    ComponentName = menuModel.ComponentName?.Trim(),
                    FullPath = menuModel.MenuPath?.Trim(),
                    Description = menuModel.Description?.Trim(),
                    MenuLevel = CalculateMenuLevel(menuModel.ParentMenuId, menuModel.MenuType),
                    IsEnabled = menuModel.IsEnabled,
                    IsVisible = menuModel.IsVisible,
                    UpdateTime = DateTime.Now
                };

                return await _repository.UpdateAsync(model) ? (true, "修改成功！") : (false, "修改失败！");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"修改菜单失败 - 菜单ID: {menuModel?.Id}");
                return (false, "系统错误，修改失败");
            }
        }

        /// <summary>
        /// 显示/隐藏菜单
        /// </summary>
        public async Task<(bool Success, string Message)> HideMenuAsync(long id)
        {
            try
            {
                MenuModel model = await _repository.GetById(id);
                if (model == null)
                {
                    return (false, "找不到该菜单");
                }

                model.IsVisible = !model.IsVisible;
                bool updateResult = await _repository.UpdateAsync(model);

                string action = model.IsVisible ? "显示" : "隐藏";
                return updateResult ? (true, $"{action}成功！") : (false, $"{action}失败！");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"切换菜单显示状态失败 - 菜单ID: {id}");
                return (false, "系统错误，操作失败");
            }
        }

        /// <summary>
        /// 启用/禁用菜单
        /// </summary>
        public async Task<(bool Success, string Message)> DeleteMenuAsync(long id)
        {
            try
            {
                MenuModel model = await _repository.GetById(id);
                if (model == null)
                {
                    return (false, "找不到该菜单");
                }

                model.IsEnabled = !model.IsEnabled;
                bool updateResult = await _repository.UpdateAsync(model);

                string action = model.IsEnabled ? "启用" : "禁用";
                return updateResult ? (true, $"{action}成功！") : (false, $"{action}失败！");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"切换菜单状态失败 - 菜单ID: {id}");
                return (false, "系统错误，操作失败");
            }
        }
    }
}